package com.reebake.ideal.storage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.reebake.ideal.storage.entity.FileInfoDTO;
import com.reebake.ideal.storage.entity.PresignedUrlParam;
import com.reebake.ideal.storage.entity.PresignedUrlResult;
import com.reebake.ideal.storage.properties.StorageProperties;
import com.reebake.ideal.storage.service.FileDetailService;
import com.reebake.ideal.storage.service.FilePresignedService;
import com.reebake.ideal.storage.service.FileRecorderService;
import com.reebake.ideal.storage.util.StorageUtil;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.dromara.x.file.storage.core.constant.Constant;
import org.dromara.x.file.storage.core.get.RemoteFileInfo;
import org.dromara.x.file.storage.core.platform.FileStorage;
import org.dromara.x.file.storage.core.presigned.GeneratePresignedUrlPretreatment;
import org.dromara.x.file.storage.core.presigned.GeneratePresignedUrlResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class FilePresignedServiceImpl implements FilePresignedService {
    @Autowired
    private StorageProperties storageProperties;
    @Autowired
    private FileStorageService fileStorageService;//注入实列
    @Autowired
    private FileRecorderService fileRecorderService;
    @Autowired
    private FileDetailService fileDetailService;

    private GeneratePresignedUrlResult signature(PresignedUrlParam presignedUrlParam) {
        String platform = presignedUrlParam.getPlatform();
        FileStorage storage;
        if(StrUtil.isBlank(platform)) {
            storage = fileStorageService.getFileStorage();
        }else {
            storage = fileStorageService.getFileStorageVerify(platform);
        }
        boolean supportPresignedUrl = fileStorageService.isSupportPresignedUrl(storage);
        if(!supportPresignedUrl) {
            return null;
        }
        String path = presignedUrlParam.getPath();
        String filename = presignedUrlParam.getFilename();
        String contentDisposition = presignedUrlParam.getContentDisposition();
        String contentType = presignedUrlParam.getContentType();
        String method = presignedUrlParam.getMethod();

        GeneratePresignedUrlPretreatment pretreatment = fileStorageService
                .generatePresignedUrl()
                .setPlatform(StrUtil.isNotBlank(platform), platform)
                .setFilename(filename)
                .setMethod(method)
                .setPath(StrUtil.isNotBlank(path), path)
                .setExpiration(DateUtil.offsetSecond(new Date(), storageProperties.getPresignedExpireIn()));

        if(Constant.GeneratePresignedUrl.Method.GET.equals(method)) {
            pretreatment
                    .putResponseHeaders(StrUtil.isNotBlank(contentDisposition)
                            , Constant.Metadata.CONTENT_DISPOSITION
                            , contentDisposition +
                                    (StrUtil.isNotBlank(contentDisposition) && contentDisposition.endsWith("=") ? filename : ""))
                    .putResponseHeaders(StrUtil.isNotBlank(contentType)
                            , Constant.Metadata.CONTENT_TYPE, contentType);
        }else {
            pretreatment
                    .putHeaders(StrUtil.isNotBlank(contentDisposition)
                            , Constant.Metadata.CONTENT_DISPOSITION, contentDisposition)
                    .putHeaders(StrUtil.isNotBlank(contentType)
                            , Constant.Metadata.CONTENT_TYPE, contentType);
        }
        return pretreatment.generatePresignedUrl();
    }

    @Override
    public PresignedUrlResult presigned(PresignedUrlParam presignedUrlParam) {
        String url = presignedUrlParam.getUrl();
        if(StrUtil.isNotBlank(url)) {
            // 获取一个 FileInfo
            FileInfo fileInfo = fileStorageService.getFileInfoByUrl(url);
            presignedUrlParam.setPath(fileInfo.getPath());
            presignedUrlParam.setFilename(fileInfo.getFilename());
            presignedUrlParam.setPlatform(fileInfo.getPlatform());
        }
        String id = presignedUrlParam.getId();
        if(StrUtil.isNotBlank(id)) {
            FileInfo fileInfo = StorageUtil.toFileInfo(fileDetailService.getById(id));
            presignedUrlParam.setPath(fileInfo.getPath());
            presignedUrlParam.setFilename(fileInfo.getFilename());
            presignedUrlParam.setPlatform(fileInfo.getPlatform());
        }
        return BeanUtil.copyProperties(signature(presignedUrlParam), PresignedUrlResult.class);
    }

    @Override
    public FileInfoDTO record(PresignedUrlParam presignedUrlParam) {
        String platform = presignedUrlParam.getPlatform();
        String path = presignedUrlParam.getPath();
        String filename = presignedUrlParam.getFilename();
        String originalFilename = presignedUrlParam.getOriginalFilename();

        //自行传入 path 及 filename 获取文件信息
        RemoteFileInfo remoteFileInfo = fileStorageService.getFile()
                .setPlatform(StrUtil.isNotBlank(platform), platform)
                .setPath(StrUtil.isNotBlank(path), path)
                .setFilename(filename)
                .getFile();
        FileInfo fileInfo = remoteFileInfo.toFileInfo();
        fileInfo.setOriginalFilename(originalFilename);
        fileRecorderService.save(fileInfo);

        return StorageUtil.toFileInfoDTO(fileInfo);
    }
}
